package org.xxpay.pay.channel.alizftpay;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xxpay.apibase.constant.ABCS;
import org.xxpay.apibase.exception.ApiException;
import org.xxpay.apibase.service.IAPIOrderService;
import org.xxpay.apibase.service.IAPISysConfigService;
import org.xxpay.apibase.service.IDCAlizftpayChannelService;
import org.xxpay.apibase.service.IDCNotifyService;
import org.xxpay.apibase.util.HttpKit;
import org.xxpay.apibase.vo.ApiPayOrder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.math.BigDecimal;
import java.util.Map;

/** 模板回调实现类 **/
@Service
public class AlizftpayPayNotifyService implements IDCNotifyService {

    @Autowired private IAPIOrderService apiOrderService;
    @Autowired private IAPISysConfigService sysConfigService;
    @Autowired private IDCAlizftpayChannelService alizftpayChannelService;

    private static final Logger logger = LoggerFactory.getLogger(AlizftpayPayNotifyService.class);
    private static final String LOG_PREFIX = "【alizftpay】";  //日志前缀

    @Override
    public void doNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {

        try {

            //1. 获取请求参数
            JSONObject params = HttpKit.convertParamMap2JSONSimple(request.getParameterMap());

            String alipayTradeNo = params.getString("trade_no");

            //2. 验签 & 获取订单对象
            ApiPayOrder payOrder = checkSignAndGetOrder(params);
            String payOrderId = payOrder.getPayOrderId();

            //3. 查询订单是否支付完成 && 返回结果
            if(payOrder.getStatus() == ABCS.PAY_ORDER_STATE.SUCCESS || payOrder.getStatus() == ABCS.PAY_ORDER_STATE.COMPLETE){ //已经支付完成， 返回完成状态

                //通知下游商户
                apiOrderService.notifySuccess2SubMch(payOrderId);
                response.getWriter().write("SUCCESS");

            }else if(payOrder.getStatus() == ABCS.PAY_ORDER_STATE.PAYING){ //支付中

                //更新订单为完成状态
                apiOrderService.updateOrderIng2Success(payOrderId, alipayTradeNo);

                //发起资金结算到二级商户
                alizftpayChannelService.tradeSettleConfirm(alipayTradeNo, payOrderId);

                //通知下游商户
                apiOrderService.notifySuccess2SubMch(payOrderId);
                response.getWriter().write("SUCCESS");
            }else{ //其他状态

                throw ApiException.build("订单状态异常！");
            }

        } catch (ApiException e) {
            response.getWriter().write("ERROR["+e.getMessage()+"]");
        }
    }

    /*
     * 功能描述:  验签 & 返回订单
     *
     * @param params 请求参数
     * @Return: void
     * @Author: xxpay
     */
    private ApiPayOrder checkSignAndGetOrder(JSONObject params){

        logger.debug("{}同步参数{}", LOG_PREFIX, params.toJSONString());
        
        //订单号
        String myselfOrderId = params.getString("out_trade_no");

        ApiPayOrder payOrder = apiOrderService.getByPayOrderId(myselfOrderId);

        if(payOrder == null){
            logger.error("{}查单失败myselfOrderId={}", LOG_PREFIX, myselfOrderId);
            throw ApiException.build("查单失败！");
        }

        Long amountL = new BigDecimal(params.getString("total_amount")).movePointRight(2).longValue(); ; //接口返回的订单金额

        if( !amountL.equals(payOrder.getAmount()) ){
            logger.error("{}订单金额验证失败， myselfAmount={}, orderAmount={}", LOG_PREFIX, payOrder.getAmount(), amountL);
            throw ApiException.build("订单金额验证失败！");
        }


        JSONObject payParamJSON = apiOrderService.getPayParamJSONByOrderId(payOrder.getPayOrderId()); //根据订单号查询通道配置信息


        try {

            boolean isVerify = false;

            AlizftpayConfig alipayConfig = new AlizftpayConfig(payParamJSON);

            if("cert".equals(alipayConfig.getEncryptionType())){  //证书方式

                String alipayPublicCertPath = sysConfigService.querySysConfig("certRootPath") + File.separator + alipayConfig.getAlipayPublicCert();
                isVerify = AlipaySignature.rsaCertCheckV1(params.toJavaObject(Map.class), alipayPublicCertPath, AlizftpayConfig.CHARSET, AlizftpayConfig.SIGNTYPE);

            }else{
                isVerify = AlipaySignature.rsaCheckV1(params.toJavaObject(Map.class), alipayConfig.getAlipayPublicKey(), AlizftpayConfig.CHARSET, AlizftpayConfig.SIGNTYPE);
            }

            if(isVerify){
                return payOrder;
            }

            logger.error("{}签名验证失败", LOG_PREFIX);
            throw ApiException.build("签名验证失败！");


        } catch (AlipayApiException e) {
            logger.error( "AlizftpaySignature.rsaCheckV1 error", e);
            throw ApiException.build("调起验签工具失败！");
        }

    }

    @Override
    public boolean doReturn(HttpServletRequest request, HttpServletResponse response) throws Exception {

        try {

            //1. 获取请求参数
            /*JSONObject params = HttpKit.convertParamMap2JSONSimple(request.getParameterMap());

            String alipayTradeNo = params.getString("trade_no");

            //2. 验签 & 获取订单对象
            ApiPayOrder payOrder = checkSignAndGetOrder(params);
            String payOrderId = payOrder.getPayOrderId();

            String returnUrl = apiOrderService.genReturnUrlByOrderId(payOrderId);
            if(StringUtils.isNotEmpty(returnUrl)){
                response.sendRedirect(returnUrl);
                return false; //跳转到指定页面
            }*/

            return true; //跳转到默认页面

        } catch (ApiException e) {

            logger.error("异常！", e);
            return true;
        }
    }

}
